home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1996 April
/
CHIP 1996 aprilis (CD06).zip
/
CHIP_CD06.ISO
/
hypertxt.arj
/
9306
/
CGAEGA2.CD
< prev
next >
Wrap
Text File
|
1995-04-16
|
22KB
|
357 lines
@VGrafikus konvertálások -- IV.@N
@VA CGA és az EGA lehetôségei@N
Sorozatunk elôzô részében részletesen tárgyaltuk, miként
lehet egy tetszôleges CGA vagy EGA képrôl valósághû
színeket tartalmazó ábrákat leképezni. Most azzal
foglalkozunk, hogy hogyan lehet ezeket a megjelenítôket
felkészíteni egy tetszôleges számú színárnyalatot
tartalmazó kép megjelenítésére, és miként tudjuk
végrehajtani a tényleges megjelenítést.
Az eljárások során mindvégig az volt az irányadó, hogy a
lehetô legjobban kihasználjuk az egyes paletták és
felbontások kínálta lehetôségeket.
@VAz üzemmódok felkészítése a köztes információ@N
@V fogadására@N
A konvertálásoknak ez az a része, amitôl minden specialista
retteg. A szakirodalom szûkszavúan palettaoptimalizálásként
tartja számon. Tényleg nem egyszerû a feladat, ami
voltaképp azt takarja, hogy miképp lehet meghatározatlanul
nagy -- esetünkben 16,7 millió -- számú szín
megjelenítéséhez a legmegfelelôbb @Kx@N számú színt
megtalálni. Az @Kx@N értelemszerûen a pillanatnyi grafikus
üzemmódban megjeleníthetô színek maximális száma (most 4
vagy 16). Ezekkel a színekkel gazdálkodhatunk majd, hogy a
lehetô legjobban megközelítsük a kívánt árnyalatokat.
Legegyszerûbb dolgunk a CGA 160x200-as felbontású, 16 színû
üzemmódjánál van, hiszen itt egyáltalán nincs választási
lehetôségünk. Nincs paletta, amirôl válogatni lehetne --
összesen 16 szín van, ezek egyidôben meg is jeleníthetôk.
Nagyon mostoha a helyzet azonban a CGA másik, 320x200
képpont felbontású, 4 színû üzemmódja esetében. A grafikus
kártya kifejlesztôinek sikerült megtalálniuk a lehetô
legrosszabb és legésszerûtlenebb megoldást a színek
megválasztásának elôsegítésére. Két palettát készítettek, e
két paletta közül választhatunk. Azonban a palettán belül
csak az egyik színt (a mindenkori háttérszínt)
választhatjuk meg szabadon, a többi elôre definiált (lásd
az elôzô részt). Ezzel gyakorlatilag lehetetlenné tették
számunkra, hogy matematikai eljárásokkal döntsünk a
színhasználatról. A fekete háttérszínt lehetne ugyan
módosítani, de ezt sem igazán érdemes, mivel erre a színre
szinte minden képfelépítésénél szükség van. Eddig tartott
a mentegetôzés amiatt, hogy igen tudománytalan módon azt
kell javasolnom, döntsön a programkörnyezet, az
illeszthetôség és a felhasználó pillanatnyi ízlése,
hangulata a két paletta felhasználása között.
Valóságos felüdülésnek tûnik ezután az EGA lehetôségeit
sorra venni. Itt a 16 színt teljesen szabadon választhatjuk
meg a 64 színt tartalmazó palettáról. Igen ám, de melyek
legyenek ezek? Ha valaki nem bízik magában, ezt a lépést
elsô közelítésben nyugodtan kihagyhatja, hiszen a grafikus
üzemmód bekapcsolásakor a palettatábla automatikusan
beállítódik egy általános, átfogó színskálát alkotva. A
konvertálás harmadik fázisa így is mûködni fog, bár a
keletkezett kép minôsége alighanem messze elmarad a
lehetôségektôl. Rengeteg módszer létezik a 16
legoptimálisabb szín kiválasztására. Ezek közül ezúttal
hárommal foglalkozunk részletesen. A VGA konvertálásokról
szóló, következô részben további néhány eljárás jóval
részletesebb tárgyalására lesz majd lehetôség. Most pedig
lássuk a medvét.
@VA színösszetolásos eljárás@N
Az elsônek az a lényege, hogy a színskálán az egymáshoz
legközelebb lévô színeket addig tologatjuk össze (kettôjük
átlagával tesszük egyenlôvé ôket), amíg már csak 16 vagy
kevesebb szín marad. Erre sok bonyolult, hosszadalmas és
rossz eljárást lehet kitalálni. Van azonban egy egyszerû,
könnyen érthetô megoldás is.
Megszámoljuk, hány szín van. Ha 16-nál több, akkor
beállítunk egy változót (x) 2-re, és egy olyan ciklust
indítunk, aminek a kilépési feltétele az, hogy a színek
száma 16 vagy annál kevesebb legyen. A ciklusban a
színtáblát X-re rendezzük. (Az X-re rendezés azt jelenti,
hogy a komponenseket egy maradék nélküli, mindig a kisebb
számra kerekítô osztással elosztjuk, majd az eredményt
x-szel visszaszorozzuk. Ezzel végül is azt érjük el, hogy
az X szélességû sávban megszüntetjük a különbségeket --
összetoljuk az értékeket. Ezután, ha a színek száma még
meghaladja a 16-ot, akkor a ciklusban megnöveljük 1-gyel az
x értékét. Egészen addig növeljük a sávszélességet, amíg a
színek száma elfogadhatóvá nem válik. Ha kiléptünk a
ciklusból, akkor a színek egy kicsit sötétebbek, mint
kellene lenniük, hiszen az osztás mindig lefelé kerekített.
Ezért végigszaladunk a színtáblán, és a színösszetevôkhöz
hozzáadunk x/2-t: középértékeket képzünk. Végül
elôállítjuk az EGA számára megfelelô, 0--3-ig terjedô
skálát. (Ha a 16,7 millió színû, 0-tól 255-ig terjedô
skálával dolgoztunk, akkor egyszerûen elosztjuk 64-gyel).
A 16 szín komponenseit belehelyezzük az EGA paletta
00rgbRGB formátumú byte-jaiba, és érvényesítjük a palettát.
@VA térbeli színkocka elve@N
A második eljárás kicsit fejlettebb és bonyolultabb is az
elôbbinél, de sokkal pontosabban közelíti meg a kívánt
színeket, és azt is biztosítja, hogy mind a 16 szín
fel legyen használva.
Képzeljünk el egy olyan térbeli kockát, amelynek három --
egy sarokban találkozó -- éle a vörös, a zöld és a kék
komponensek skálája, a feketétôl az adott szín teljes
telítettségéig. Válasszuk az éleket mondjuk 5 bites
felbontásúra, ami azt jelenti, hogy a színkocka térfogata
32x32x32 = 32|768 elem lesz. Minden elem egy színt
reprezentál a teljes színskálából, amely a kocka belsejében
helyezkedik el. Minden elemet feleltessünk meg egy
számlálónak, amely azt tartalmazza majd, hogy az
optimalizálandó képen hány olyan színû/színtartományba esô
pixel van, amit a számlálóelem három színkoordinátája
meghatároz. Töltsük fel ezeket a számlálókat úgy, hogy az
optimalizálandó kép minden pixelén végigfutunk, és
megnöveljük a neki megfelelô számlálót. Ezután a kocka
éleit felezgetve -- majd a keletkezett darabokat tovább
vágva leghosszabb élük mentén -- hozzunk létre 16 egyenlô
térfogatú darabot, és vizsgáljuk meg, hogy közülük hány nem
tartalmaz egyáltalán pixeleket.
Ha találtunk ilyen ""üres" darabot, akkor a legtöbb pixelt
tartalmazó darabot ismét elfelezzük, az üreset pedig
eldobjuk. ùjra kiértékeljük a kis színkocka-darabokat. A
mûveletsort addig folytatjuk, amíg csak találunk üres
darabokat (és van még vágható kockadarab). A végén a
színkocka-darabokban összeátlagoljuk a színelemeket
elôfordulásuk arányában, és ezeket feleltetjük meg a
végleges palettaelemeknek.
@VA színfelület-függô kiejtés algoritmusa@N
A harmadik eljárás kicsit egyszerûbb, de figyelembe veszi
azt a nyilvánvaló tényt is, hogy a nagyobb felületeket
takaró színtartományoknak több árnyalatot kell biztosítani,
mint a pontszerûen felbukkanó színeknek. Elôször az elsô
eljárást használva rendezzük a színtáblát mondjuk úgy, hogy
csak 32 szín maradjon. Ezután a 32 színt és X-et (az
osztót) eltároljuk, majd visszatöltjük az eredeti
palettatáblát. Mind a 32 szín esetében megszámoljuk, hogy
az eredeti színtáblán az adott szín mellett X
sávszélességen belül hányszor fordul elô szín. Ezután a 32
színt sorba rendezzük a hozzájuk rendelt elôfordulási
arányszámok szerint, és kiválasztjuk a 16 legnagyobb
értékût. Ezek a színek lesznek tehát, amelyeket a palettába
beleszámítunk. Innentôl kezdve minden ugyanúgy megy, mint
az elôbbiekben. Természetesen nem kell tartanunk magunkat
a 32-es számhoz, kísérletezhetünk nagyobbakkal vagy
kisebbekkel is, célunknak megfelelôen.
Ennek az eljárásnak létezik egy továbbfejlesztett
változata, amely szintén a térbeli színkockát használja
kiértékeléshez, és a túl kevés elemet tartalmazó
kockadarabokat is eldobja, nem csak az üreseket.
Mivel azonban az EGA és a VGA palettaoptimalizáló eljárásai
nagymértékben hasonlítanak egymáshoz, ezt a lényegesen
összetettebb mûveletsort a sorozat következô részében
tárgyaljuk majd részletesebben.
@VA köztes file megjelenítése@N
Ez talán valamivel egyszerûbb kérdés, mint a paletta
optimalizálása. Néhány eljárás megfelelô kombinálásával a
lehetôségekhez mérten viszonylag jó képeket építhetünk fel,
anélkül, hogy bonyolult és érthetetlen matematikai
összefüggéseket kellene alkalmaznunk. Az egyik ilyen
eljárás a színkiválasztó algoritmus. Mindhárom típusú
megjelenítés használni fogja, ezért a legalapszintûbb
függvénynek tekinthetô. Feladata az, hogy a hívótól
komponenshármas (vörös, zöld, kék) formában megkapott
""kívánt" színhez a palettát letapogatva megkeresse a
""kívánt" színt legjobban kifejezô fizikai színértéket
(vagyis a palettatábla ezen elemének indexét). Az eljárás
mûködésének a lényege tehát az, hogy végigszalad a teljes
palettatáblán, és minden egyes elem esetében
komponenskülönbség-összegeket képez a kívánt szín és a
paletta aktuális eleme között (akárcsak a többfázisú
átlagképzés esetében a mezôk között). Ezután a palettatábla
azon elemét választja ki, ahol ez az összeg a legkisebb
volt (ami azt jelenti, hogy ez hasonlított legjobban a
kívánt színre). Az elem indexét pedig mint színértéket
visszaadja a hívónak.
@VA CGA üzemmódok lehetôségei@N
Ezek után lássuk a megjelenítési eljárásokat a különbözô
üzemmódokban! A CGA 160x200-as, igen kis felbontása mellett
ábrázolható 16 színnel nem raszterezhetjük a képet. Meg
kell elégednünk azzal, hogy a köztes file-ból lekérjük az
adott pont színhármasát, átadjuk a színkeresô
algoritmusnak, és a visszatérô értéket a képernyôre
küldjük. A színkeresô algoritmusnak CGA módok esetén az 1.
tábla adatait kell használnia palettaként (lásd CHIP
1993/4/84). A 320x200-as, négyszínû üzemmódban is
eljátszhatjuk ugyanezt, de ekkor ne számítsunk túl jó
képre. Itt a nagyobb felbontás miatt már megengedhetünk
magunknak némi raszterhasználatot, sôt, ez a színek kis
száma miatt elengedhetetlen is.
Kétpontos rasztert készítünk, a képernyôt sakktáblaszerûen
felosztva. Matematikailag a sakktábla fehér pontjait az
@K(A+B) mod 2 = 0@N kifejezés igaz értéke jelenti, a fekete
mezôket pedig ennek hamissága. A képletben az @KA@N és a
@KB@N az adott pont koordinátái, a @Kmod@N pedig egy olyan
mûvelet, ami osztást végez, és eredményként a maradékot
adja vissza. Ha két pontot használhatunk egy szín
kifejezésére, akkor ezek átlagának kell megegyeznie az
adott színnel. Ezért a ""fehér" kockákon ugyanazt az
eljárást követjük, mint eddig (a kívánt színhármast
leadjuk, az eredményt megjelenítjük). Ha azonban ""fekete"
kockán vagyunk, akkor jóval összetettebb lesz a mûveletsor.
Elôször itt is elkérjük az eredményt a színkiválasztó
algoritmusunktól, és eltároljuk a talált színhez tartozó,
létezô komponenshármast. Az a célunk, hogy az átlag fejezze
ki a kívánt színt, tehát a másik szín megfelelô elemeinek
és a talált összetevôknek úgy kell elhelyezkedniük, hogy a
kívánt szín komponensértékei éppen a két elôzô
komponensérték közötti szakasz felezôpontján helyezkedjenek
el az alapszínek skáláján.
Ezt a legegyszerûbben úgy tudjuk elérni, hogy a talált
komponensértékeket az alapszínskálán, a kívánt szín azonos
összetevôin tükrözzük; azaz a megtalált és a kívánt
összetevôk értékei közötti különbséget hozzáadjuk a kívánt
szín megfelelô komponensértékeihez, és az átvetítés
eredménye adja a második szín megfelelô összetevôjét.
Képlettel: @KXMásodik = XKívánt + (Xkívánt - Xtalált),@N
ahol az @KX@N a vörös, a zöld vagy a kék összetevôt
jelenti. A tükrözés során elôfordulhat, hogy a második
érték valamelyik komponense 0 alá vagy a maximum fölé
emelkedik. Ezt muszáj ellenôrizni. Ha bekövetkezik, akkor
fel kell tolni 0-ig, vagy vissza kell húzni a maximum
értékig a bûnös összetevôt. Az elôzô részben (1993/4/82)
szereplô citromsárga szín beállítása szemlélteti a
mûveletet.
Miután megszereztük a második szín összes komponensét, az
eredményt átadjuk a színkeresô eljárásnak, és a
visszakapott színértéket jelenítjük meg. Ez az eljárás a
tükrözôs színkeresés. Célszerû úgy megírni, hogy a kívánt
színértéket komponenshármas formájában kapja meg, és a
második szín értékét adja vissza. Még valami: a CGA ezen
üzemmódjánál vigyáznunk kell arra, hogy az alappaletta
táblázatot (lásd CHIP 1993/4/82) használó eredeti
színkeresô eljárás és egyáltalán minden hivatkozás a
táblázatra ne közvetlen indexeléssel történjen, hiszen a
színértéket elôbb még egyeztetni kell az érvényes belsô
palettával és háttérszínnel.
@VAz EGA lehetôségei@N
Az EGA kisfelbontású üzemmódjaiban (320x200, 640x200) sem
érdemes egyebekkel vacakolni. Használjuk az elôbbi rutint
azzal a kiegészítéssel, hogy most 16 színnel és az EGA
saját palettatáblájával van dolgunk. A nagyobb felbontások
esetében (640x350, 640x480) megkeverhetjük egy kicsit a
dolgokat. Például minden egyes megjelenítendô színponthoz
hozzárendelhetünk egy valódi 2x2-es rasztermezôt, méghozzá
a felbontás látható romlása nélkül. Ezen a felületen 4
fokozatos skálabontás mellett 4096 (4x(2x2) a harmadikon)
különbözô színt szimulálhatunk. Persze ez legalább a
negyedére csökken amiatt, hogy egyszerre csak 16 színt
használhatunk. Ne essünk kétségbe, inkább kezdjük el
felépíteni logikai pixelünket.
A tükrözôs színkeresésnek egy olyan változatát fogjuk
használni, ami ismeri a kívánt színérték összetevôit,
paraméterként egy másik szín (a késôbbiekben a korrigálandó
átlag) komponenseit kapja meg. Azeljárás olyan színértéket
ad vissza, amit a paraméterként kapott összetevôhármas
kívánt értéken való átvetítésével határoz meg (tehát
ugyanaz, mint a CGA esetében, csak most a korrigálandó
értéket mi határozzuk meg, nem keresi meg automatikusan --
ezzel szemben egy belsô változóból ismeri a kívánt szín
összetevôit).
Az eljárás a következô. Olvassuk ki a köztes file-ból a
kívánt színt. Elôször állítsunk be ennek megfelelôen egy
belsô színleíró változót a módosított tükrözô algoritmus
számára, hogy ezt a késôbbiekben ne kelljen neki átadni. A
kiolvasott szín komponenseit adjuk át az eredeti színkeresô
algoritmusnak is, ami most az éppen érvényes EGA palettát
használja. A visszakapott színt egyrészt helyezzük el a
2x2-es raszter bal felsô sarkába, másrészt a szín megtalált
fizikai összetevôit (vörös, zöld, kék) tároljuk el külön
egy változóba. Ez a változó (mondjuk Y rekord) lesz a
változó átlagú raszterképzés pillanatnyi átlaga. Most
tulajdonképpen ugyanazt fogjuk tenni, mint a CGA esetében:
meghívjuk a tükrözôs színkeresô eljárást az Y átlag három
értékével, hogy korrigáljuk a kívánt és a talált szín
eltérését.
A visszakapott színt a raszter jobb alsó sarkába helyezzük.
Ezután -- és ez nagyon fontos -- a most talált szín fizikai
összetevôit és az Y változó megfelelô komponenseit
átlagoljuk, és az eredményeket visszarakjuk az Y-ba. Ezt
kell tennünk, hiszen az Y a mindenkori komponensátlagokat
tárolja, és ebben most már a második pont komponensei is
benne vannak. Ugyanezt elvégezzük a fennmaradó két ponttal
is. Tehát a már módosított Y komponenseit átadjuk a
tükrözôs színkeresésnek, a visszakapott színt a jobb felsô
sarokba rakjuk, a talált szín igazi komponenseit átlagoljuk
az Y-nal. Az Y-t utoljára még egyszer átadjuk a tükrözôs
színkeresésnek, a színt belehelyezzük a fennmaradt pont
helyére a bal alsó sarokba. Az átlagképzést ezután
tulajdonképpen nincs értelme végrehajtani, hiszen többé
nincs szükségünk Y-ra. Látható, hogy így a kívánt színt
lépésenként, egyre jobban és finomabban megközelítve
állítjuk elô a megfelelô színhatást.
A legjobb minôségû képeket mégsem ez az eljárás
szolgáltatja, hanem a hibaszórásos algoritmus színes
változata. Az eljárás tulajdonképpen ugyanaz, mint ami a
""Grafikus konvertálások -- Monokróm üzemmódok lehetôségei
2." címû cikkben (CHIP 1993/február 63. old.) ismertettünk,
csupán néhány részlet és kikötés módosul a színhasználat
miatt. A ""hiba" változó most három külön változó lesz,
hiszen a hibák színkomponensenként más-más jelentôségûek
lehetnek. A színpontkirakó eljárás a koordináták mellett
természetesen három adatot kap a vörös, a zöld és a kék
kívánt színtelítettségekre nézve. E komponenseket a
megfelelô hibaértékek figyelembevételével módosítva átadja
a színkeresô eljárásnak, hogy visszakapja a keresett
kompenzációs szín indexét (ez az a lépés, amely a monokróm
változatban egyszerû döntés volt -- azaz hogy a kapott
fényesség a hibával összegezve félfényesség alatt vagy
fölött van-e).
A hibakomponenseket természetesen ugyanúgy kell módosítani
külön-külön, ahogyan azt a monokróm fényességi
hibaváltozóval tettük. Az egyetlen különbség, hogy a
hibaváltozó abszolút értékét nem szabad 255 fölé növelni,
azaz a komponenshibákat a -255 és +255 közötti
intervallumban kell tartani, hiszen ennél nagyobb hibát
úgysem lehet egy lépésben kompenzálni. Ennek a kikötésnek
egyébként ritkán lesz jelentôsége, mert nagyon ritkán
fordul elô, hogy sorozatos hibaképzôdések miatt ekkora
komponensátlag eltérések jöjjenek létre.
@KNagy Gergely@N